package com.naodong.shenluntiku.mvp.view.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.blankj.utilcode.util.SizeUtils;
import com.naodong.shenluntiku.R;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by hujie on 17/6/13.
 */

public class TopTipViewManager {


    private LinkedList<String> tipQueue;//需要显示的提示队列
    private TopTipView topTipView;
    private Disposable showDisposable;
    private Disposable hideDisposable;


    public TopTipViewManager(ViewGroup viewGroup) {
        topTipView = new TopTipView(viewGroup);
        tipQueue = new LinkedList<>();
    }

    public void showTipView(String text) {
        tipQueue.addLast(text);
        createShowObserable();
    }

    private synchronized void createShowObserable() {

        if (showDisposable != null && !showDisposable.isDisposed()) {
            return;
        }
        showDisposable = Observable.create((ObservableOnSubscribe<String>) e -> {
            while (tipQueue.size() > 0) {
                e.onNext(tipQueue.get(0));
                while (topTipView != null && (topTipView.isRunning() || topTipView.isVisible())) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e1) {

                    }
                }
            }
            e.onComplete();
        }).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                if (topTipView != null && !topTipView.isVisible()) {
                    topTipView.show(s);
                    createHideObserable();
                    tipQueue.pop();
                }
            }
        }, throwable -> {

        });


    }

    private void createHideObserable() {
        disposeHideDisposable();
        hideDisposable = Observable.timer(5, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(aLong -> {
            if (topTipView != null && topTipView.isVisible()) {
                topTipView.hide();
            }
        });
    }

    private void disposeHideDisposable() {
        if (hideDisposable != null && !hideDisposable.isDisposed()) {
            hideDisposable.dispose();
            hideDisposable = null;
        }
    }


    private void disposeShowDisposable() {
        if (showDisposable != null && !showDisposable.isDisposed()) {
            showDisposable.dispose();
            showDisposable = null;
        }
    }


    public void destory() {
        disposeHideDisposable();
        disposeShowDisposable();
        topTipView.destory();
    }

    class TopTipView {

        private ViewGroup mParent;//must be Linearlayout
        private Context mContext;
        private View mView;
        private TextView tipTV;
        private ValueAnimator valueAnimator;

        private void destory() {
            mContext = null;
            valueAnimator.cancel();
            mParent.removeAllViews();
            mView = null;
            mParent = null;
            tipTV = null;
            valueAnimator = null;
        }


        TopTipView(ViewGroup view) {
            mParent = view;
            mContext = view.getContext();
            mView = LayoutInflater.from(mContext).inflate(R.layout.top_tip_view, null);
            mParent.addView(mView, 0);
            tipTV = (TextView) mView.findViewById(R.id.tipTV);
            mView.findViewById(R.id.removeView).setOnClickListener(v -> {
                disposeHideDisposable();
                hide();
            });

        }


        public void show(String text) {
            tipTV.setText(text);
            animHeightToView(mView, true, 500);
        }

        void hide() {
            animHeightToView(mView, false, 500);
        }


        boolean isRunning() {
            return valueAnimator != null && valueAnimator.isRunning();
        }

        // 高度渐变的动画；
        void animHeightToView(final View v, final int start, final int end, final boolean isToShow,
                              long duration) {
            valueAnimator = ValueAnimator.ofInt(start, end);
            final ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
            valueAnimator.addUpdateListener(animation -> {
                int h = (int) animation.getAnimatedValue();
                layoutParams.height = h;
                v.setLayoutParams(layoutParams);
                v.requestLayout();

            });

            valueAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    if (isToShow) {
                        v.setVisibility(View.VISIBLE);
                    }
                    super.onAnimationStart(animation);
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    if (!isToShow) {
                        v.setVisibility(View.GONE);
                    }

                }
            });
            valueAnimator.setDuration(duration);
            valueAnimator.start();

        }

        public boolean isVisible() {
            if (mView!=null&&mView.getVisibility() == View.VISIBLE) {
                return true;
            }
            return false;
        }

        public void animHeightToView(final View v, final boolean isToShow, final long duration) {
            if (isRunning()) {
                return;
            }
            if (isToShow) {
                int end = SizeUtils.dp2px(70);
                animHeightToView(v, 0, end, isToShow, duration);
            } else {
                // 隐藏：从当前高度变化到0，最后设置不可见；
                animHeightToView(v, v.getLayoutParams().height, 0, isToShow, duration);
            }


        }


    }


}
